const express = require("express");
const { Sequelize, DataTypes, Model } = require("sequelize");

const app = express();
app.use(express.json());

app.use(express.static("public"));

const sequelize = new Sequelize("test", "testuser", "testpassword", {
  host: "localhost",
  dialect: "mysql",
  port: 3306,
  dialectOptions: {
    dateStrings: true,
    typeCast: true,
    timezone: "+08:00",
  },
  timezone: "+08:00", //for writing to database
  logging: true, // disable logging
});
class User extends Model {}

User.init(
  {
    uuid: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      primaryKey: true,
    },
    username: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true,
      validate: {
        isEmail: true,
      },
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    isAdmin: {
      type: DataTypes.BOOLEAN,
      defaultValue: false,
    },
    birthday: {
      type: DataTypes.DATEONLY,
      allowNull: true,
    },
    credit: {
      type: DataTypes.DECIMAL(10, 2),
      allowNull: false,
      defaultValue: 0.0,
    },
    status: {
      type: DataTypes.ENUM("active", "inactive"),
      defaultValue: "active",
    },
  },
  {
    sequelize,
    modelName: "User",
    // paranoid 是一个模型选项，用于控制软删除（也称为逻辑删除）功能。
    // 当 paranoid 被设置为 true 时，Sequelize 将会自动为模型启用软删除特性。
    // 软删除是一种在数据库中标记数据为已删除状态而非实际物理删除的技术
    // paranoid: true,
    timestamps: true,
  }
);

class Profile extends Model {}

Profile.init(
  {
    userId: {
      type: DataTypes.UUID,
      references: {
        model: User,
        key: "uuid",
      },
    },
    fullName: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    bio: DataTypes.TEXT,
    avatar: DataTypes.BLOB,
  },
  {
    sequelize,
    modelName: "Profile",
  }
);

User.hasOne(Profile, {
  foreignKey: "userId", // Add the foreign key option
  onDelete: "CASCADE",
  onUpdate: "CASCADE",
});
Profile.belongsTo(User, {
  foreignKey: "userId", // Add the foreign key option
  onDelete: "CASCADE", // Add the onDelete option
});

sequelize.sync();

app.post("/users", async function (req, res) {
  try {
    console.log("req.body", req.body);

    const { username, email, password, fullName, bio } = req.body;

    const user = await User.create(
      {
        username,
        email,
        password,
        credit: 0.0, // Set a default value for the credit field
        Profile: {
          fullName,
          bio,
        },
      },
      {
        include: [Profile],
      }
    );

    res.json(user);
  } catch (error) {
    console.error("Error creating user:", error.message);
    console.error("Validation errors:", error.errors);
    // Prepare validation errors for client
    let clientErrors = error.errors.map((err) => {
      return {
        message: err.message,
        type: err.type,
        path: err.path,
        value: err.value,
      };
    });

    res
      .status(500)
      .json({ error: "Error creating user", validationErrors: clientErrors });
  }
});

app.get("/users", async function (req, res) {
  const users = await User.findAll({
    include: [Profile], // Include the associated Profile model
  });

  // Map the results to include the fullName property from the associated Profile
  const mappedUsers = users.map((user) => {
    return {
      uuid: user.uuid,
      username: user.username,
      email: user.email,
      fullName: user.Profile ? user.Profile.fullName : null,
      bio: user.Profile ? user.Profile.bio : null,
    };
  });

  console.log("Users count:", users.length);
  console.log("Mapped users count:", mappedUsers.length);

  res.json(mappedUsers);
});

app.put("/users/:uuid", async function (req, res) {
  try {
    const { username, email, password, fullName, bio } = req.body;
    const user = await User.findByPk(req.params.uuid, {
      include: [Profile],
    });

    if (user) {
      // 更新 User 模型的字段
      user.username = username;
      user.email = email;
      // user.password = password;

      // 如果 Profile 存在，则更新其字段
      if (user.Profile) {
        user.Profile.fullName = fullName;
        user.Profile.bio = bio;
        await user.Profile.save();
      } else {
        // 如果 Profile 不存在，则创建新的 Profile 记录并关联到 User
        const profile = await Profile.create({
          fullName,
          bio,
          userId: user.uuid,
        });
        user.Profile = profile;
      }

      // 保存 User 模型的更改
      await user.save();

      res.json(user);
    } else {
      res.status(404).json({ error: "User not found" });
    }
  } catch (error) {
    console.error("Error updating user:", error.message);
    console.error("Validation errors:", error.errors);

    // 准备验证错误信息发送给客户端
    let clientErrors = error.errors.map((err) => {
      return {
        message: err.message,
        type: err.type,
        path: err.path,
        value: err.value,
      };
    });

    res
      .status(500)
      .json({ error: "Error updating user", validationErrors: clientErrors });
  }
});

app.delete("/users/:uuid", async function (req, res) {
  try {
    console.log("Deleting user with uuid:", req.params.uuid);

    const user = await User.findByPk(req.params.uuid);
    if (!user) {
      return res.status(404).json({ error: "User not found" });
    }

    // Delete the associated profile first
    const profile = await Profile.findOne({ where: { userId: user.uuid } });
    if (profile) {
      await profile.destroy();
    }

    // Now, delete the user
    await user.destroy();

    console.log("User deleted successfully:", user.uuid);
    res.json({ success: true });
  } catch (error) {
    console.error("Error deleting user:", error.message);
    res.status(500).json({ error: "Error deleting user" });
  }
});

app.listen(3000, function () {
  console.log("App running on port 3000");
});
